package com.yisin.www.chat;

import java.net.Socket;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import net.sf.json.JSONObject;

import com.yinsin.method.CallBack;
import com.yisin.ipseeker.IPLocation;
import com.yisin.ipseeker.IPSeeker;
import com.yisin.pbox.frame.common.RootContext;
import com.yisin.pbox.frame.log.ILogger;
import com.yisin.pbox.frame.log.LogFactory;
import com.yisin.pbox.frame.util.DateUtil;
import com.yisin.pbox.frame.util.StringUtil;

public class ChatServlet extends CallBack {
	private static ILogger logger = LogFactory.getDefaultLogger(ChatServlet.class);

	private static ChatServlet chat = new ChatServlet();
	public static Map<String, Map<String, String>> userMap = new HashMap<String, Map<String, String>>();
	public static Map<String, String> ipUser = new HashMap<String, String>();
	// private IUserInfoService service = (IUserInfoService)
	// SpringContainer.getBeanByName("userInfoService");
	public static Map<String, Object> msgMap = new HashMap<String, Object>();
	public static ChatRobot cr = new ChatRobot();
	public static boolean creaed = false;

	private ChatServlet() {

	}

	public static ChatServlet getChat() {
		return chat;
	}

	public static Map<String, String> getUser(String userId) {
		return userMap.get(ipUser.get(userId));
	}

	public static String getUserId(Socket soc) {
		String uid = null;
		String key = soc.getRemoteSocketAddress().toString();
		Map<String, String> user = userMap.get(key);
		if (user != null) {
			uid = user.get("userId");
		}
		return uid;
	}

	public static Socket getUserSocket(String userId) {
		return socketMap.get(ipUser.get(userId));
	}

	public Map<String, Object> getMap() {
		return new HashMap<String, Object>();
	}

	@Override
	public String accept(Socket soc) {
		String key = soc.getRemoteSocketAddress().toString();
		socketMap.put(key, soc);
		logger.info("accept==========" + key);
		return key;
	}

	@Override
	public void closed(Socket soc) {
		String key = soc.getRemoteSocketAddress().toString();
		logger.info("closed==========" + key);
		userCloseInfo(soc, key);
	}

	@Override
	public void receiveData(Socket soc, String str) {
		try {
			logger.info("receiveData==========" + str);
			createRobot();
			if (!StringUtil.isEmpty(str) && str.length() > 5) {
				String key = soc.getRemoteSocketAddress().toString();
				String cmd = str.substring(0, 4);
				if (cmd.equals("cmd●")) { // 指令
					str = str.substring(4);
					String[] data = str.split("□");
					cmd = data[0];
					if (cmd.equals("loginchat")) { // 登录聊天
						JSONObject json = JSONObject.fromObject(data[1]);
						Map<String, String> userInfo = new HashMap<String, String>();
						userInfo.put("userId", json.getString("userId"));
						userInfo.put("name", json.getString("name"));
						userInfo.put("email", json.getString("email"));
						userInfo.put("mobile", json.getString("mobile"));
						userInfo.put("header", json.getString("header"));
						userInfo.put("qq", json.getString("qq"));
						userInfo.put("sex", json.getString("sex"));
						userInfo.put("ip", key);
						userInfo.put("city", getCityByIp(key));

						if (ipUser.containsKey(userInfo.get("userId"))) {
							String oldkey = ipUser.get(userInfo.get("userId"));
							if (!oldkey.equals(key)) {
								socketMap.remove(oldkey);
								userMap.remove(oldkey);
							}
						}
						ipUser.put(userInfo.get("userId"), key);
						socketMap.put(key, soc);
						userMap.put(key, userInfo);

						pushUserLogin(soc, userInfo);

						sendSystemMsg("欢迎<span class=\"tou atuser\" uid=\"" + userInfo.get("userId") + "\">" + userInfo.get("name") + "</span>进入Hid Chat-隐聊，希望玩得快乐，聊的开心。<img src=\""+RootContext.getRootName()+"/pages/chats/images/face1/4.gif\">");

					} else if (cmd.equals("logoutchat")) { // 退出聊天
						pushUserLogout(key);
					} else if (cmd.equals("chat")) { // 聊天
						System.out.println("Data 1 --> " + data[1]);
						JSONObject obj = JSONObject.fromObject(data[1]);
						String touser = StringUtil.objectToString(obj.get("touser"));
						JSONObject msgObj = (JSONObject) obj.get("msg");
						String fromuser = StringUtil.objectToString(obj.get("fromuser"));
						Map<String, String> fUser = getUser(fromuser);
						msgMap = getMap();
						msgMap.put("fromName", fUser.get("name"));
						msgMap.put("fromId", fUser.get("userId"));
						msgMap.put("msg", msgObj);
						msgMap.put("time", DateUtil.format(new Date()));
						msgMap.put("genre", 3);// 聊天
						if (touser.equals("all_user")) { // 群聊
							String tUserId = null;
							for (Socket tosoc : socketMap.values()) {
								if (!getUserId(tosoc).equals(fromuser)) {
									tUserId = getUserId(tosoc);
									msgMap.put("touser", tUserId);
									msgMap.put("flag", 1);// 群聊
									sendMsgToClient(tosoc, mapToJsonString(msgMap));
								}
							}

							cr.checkAndRe(null, fromuser, null, msgObj, 10);
						} else { // 私聊
							Socket tosoc = getUserSocket(touser);
							if (tosoc != null) {
								msgMap.put("touser", touser);
								msgMap.put("flag", 2);// 私聊
								sendMsgToClient(tosoc, mapToJsonString(msgMap));
							} else {
								cr.checkAndRe(soc, fromuser, touser, msgObj, 10);
							}
						}
					} else if (cmd.equals("action")) { // 动作
						System.out.println("Data 1 --> " + data[1]);
						JSONObject obj = JSONObject.fromObject(data[1]);
						String touser = StringUtil.objectToString(obj.get("touser"));
						String action = StringUtil.stringUncode(StringUtil.objectToString(obj.get("action")));
						String fromuser = StringUtil.objectToString(obj.get("fromuser"));
						Map<String, String> fUser = getUser(fromuser);
						msgMap = getMap();
						msgMap.put("fromName", fUser.get("name"));
						msgMap.put("fromId", fUser.get("userId"));
						msgMap.put("action", action);
						msgMap.put("time", DateUtil.format(new Date()));
						msgMap.put("genre", 4);// 动作
						if (touser.equals("all_user")) { // 对大家
							String tUserId = null;
							for (Socket tosoc : socketMap.values()) {
								if (!getUserId(tosoc).equals(fromuser)) {
									tUserId = getUserId(tosoc);
									msgMap.put("touser", tUserId);
									msgMap.put("flag", 1);// 对大家
									sendMsgToClient(tosoc, mapToJsonString(msgMap));
								}
							}
						} else { // 个人
							Socket tosoc = getUserSocket(touser);
							msgMap.put("touser", touser);
							msgMap.put("flag", 2);// 个人
							sendMsgToClient(tosoc, mapToJsonString(msgMap));
						}
					} else if (cmd.equals("getUserList")) { // 获取列表
						pushUserList(soc);
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void sendMsgToClient(Socket tosoc, String msg) {
		sendDataToClient(tosoc, msg);
	}

	// 发送系统消息
	public void sendSystemMsg(String msg) {
		msgMap = getMap();
		msgMap.put("genre", 10);// 系统消息
		msgMap.put("time", DateUtil.format(new Date()));
		for (Socket tosoc : socketMap.values()) {
			msgMap.put("msg", msg);
			sendMsgToClient(tosoc, mapToJsonString(msgMap));
		}
	}

	public void createRobot() {
		if (!creaed) {
			creaed = true;
			cr.createRobot(60); // 初始化时创建机器人数量
			try {
				cr.startThread();
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	public void pushUserList(Socket soc) {
		logger.info("push user List to " + soc.getRemoteSocketAddress().toString());
		new Thread(new PushThread(soc)).start();
	}

	// 推送用户登录信息
	public void pushUserLogin(Socket soc, Map<String, String> userInfo) {
		msgMap = getMap();
		msgMap.put("genre", 1);// 登录聊天
		msgMap.put("loginout", 1);
		msgMap.put("time", DateUtil.format(new Date()));
		String uid = "";
		for (Socket tosoc : socketMap.values()) {
			uid = getUserId(tosoc);
			if (uid != null && !uid.equals(userInfo.get("userId"))) {
				msgMap.put("user", userInfo);
				sendMsgToClient(tosoc, mapToJsonString(msgMap));
			}
		}

		if (soc != null) {
			msgMap = getMap();
			msgMap.put("genre", 0);// 登录成功
			msgMap.put("time", DateUtil.format(new Date()));
			msgMap.put("user", userInfo);
			sendMsgToClient(soc, mapToJsonString(msgMap));
		}
	}

	// 推送用户退出信息
	public void pushUserLogout(String key) {
		Map<String, String> u = userMap.get(key);
		String userId = u.get("userId");
		String name = u.get("name");
		try {
			msgMap = getMap();
			msgMap.put("genre", 2);// 退出聊天
			msgMap.put("loginout", 2);
			msgMap.put("time", DateUtil.format(new Date()));
			for (Socket tosoc : socketMap.values()) {
				msgMap.put("userId", userId);
				msgMap.put("name", name);
				sendMsgToClient(tosoc, mapToJsonString(msgMap));
			}
		} catch (Exception e) {
		}
		// 删除
		userMap.remove(key);
		ipUser.remove(userId);
		socketMap.remove(key);
	}

	/**
	 * 用户异常关闭消息
	 * 
	 * @param soc
	 * @param key
	 */
	public void userCloseInfo(Socket soc, String key) {
		Map<String, String> userInfo = userMap.get(key);
		try {
			msgMap = getMap();
			for (Socket tosoc : socketMap.values()) {
				if (getUserId(tosoc) != null) {
					msgMap.put("userId", userInfo.get("userId"));
					msgMap.put("name", userInfo.get("name"));
					msgMap.put("genre", "5"); // 异常退出
					sendMsgToClient(tosoc, mapToJsonString(msgMap));
				}
			}

			userMap.remove(key);
			ipUser.remove(getUserId(soc));
			socketMap.remove(key);
		} catch (Exception e) {
		}
	}

	public String getCityByIp(String kip) {
		String ip = kip.substring(kip.indexOf("/") + 1, kip.indexOf(":"));
		IPSeeker seek = new IPSeeker();
		IPLocation loca = seek.getIPLocation(ip);
		String city = StringUtil.excNullToString(loca.getCountry());
		if (city.length() < 1) {
			city = "未知城市";
		}
		return city;
	}

	public String mapToJsonString(Map<String, Object> map) {
		String resultMsg = JSONObject.fromObject(map).toString();
		resultMsg = resultMsg.replaceAll(" ", "%2520");
		return resultMsg;
	}
}
